package com.macaline.technology.es;

import org.apache.http.HttpHost;
import org.apache.log4j.Logger;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;

import java.io.IOException;
import java.util.Map;


public class EsClient {


    private static Logger log = Logger.getLogger(EsClient.class.getSimpleName());


    private static RestHighLevelClient client = null;

    /**
     * 获取客户端
     * @return
     */
    public static RestHighLevelClient getClient(){
        if(client == null){
            client = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("localhost", 9200, "http"))
            );
        }
        return client;
    }

    /**
     * 关闭客户端
     * @throws IOException
     */
    public static void close() throws IOException {
        getClient().close();
    }


    /**
     * 创建索引
     * @param indexName 索引名称
     * @throws IOException
     */
    public static void createIndex(String indexName) throws IOException {
        try {
            CreateIndexRequest request = new CreateIndexRequest(indexName);
            CreateIndexResponse response = getClient().indices().create(request, RequestOptions.DEFAULT);
            boolean acknowledged = response.isAcknowledged();
        }finally {
            close();
        }
    }


    /**
     * 查询索引
     * @param indexName 索引名称
     * @return
     * @throws IOException
     */
    public static GetIndexResponse getIndex(String indexName) throws IOException {
        try {
            GetIndexRequest request = new GetIndexRequest(indexName);
            GetIndexResponse response = getClient().indices().get(request, RequestOptions.DEFAULT);
            return response;
        }finally {
            close();
        }
    }
    /**
     * 删除索引
     * @param indexName 索引名称
     * @return
     * @throws IOException
     */
    public static Boolean deleteIndex(String indexName) throws IOException {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(indexName);
            AcknowledgedResponse res = getClient().indices().delete(request, RequestOptions.DEFAULT);
            return res.isAcknowledged();
        }finally {
            close();
        }
    }

    /**
     * 添加文档
     * @param indexName 索引名称
     * @param id id
     * @param doc 内容
     * @return
     * @throws IOException
     */
    public static Boolean insertDoc(String indexName, String id, String doc) throws IOException {
        try {
            IndexRequest request = new IndexRequest();
            request.index(indexName).id(id);
            request.source(doc, XContentType.JSON);
            IndexResponse response = getClient().index(request, RequestOptions.DEFAULT);
            if(!"CREATE".equals(response.getResult())){
                return false;
            }
            return true;
        }finally {
            close();
        }
    }

    /**
     * 修改文档
     * @param indexName 索引名称
     * @param id id
     * @param params 修改内容
     * @return
     * @throws IOException
     */
    public static Boolean updateDoc(String indexName, String id, Map params) throws IOException {
        try {
            UpdateRequest request = new UpdateRequest();
            request.index(indexName).id(id);
            request.doc(params);
            UpdateResponse response = getClient().update(request, RequestOptions.DEFAULT);
            if(!"UPDATED".equals(response.getResult())){
                return false;
            }
            return true;
        }finally {
            close();
        }
    }


    /**
     * 查询文档
     * @param indexName 索引名称
     * @param id id
     * @return
     * @throws IOException
     */
    public static String getDoc(String indexName, String id) throws IOException {
        try {
            GetRequest request = new GetRequest();
            request.index(indexName).id(id);
            GetResponse response = getClient().get(request, RequestOptions.DEFAULT);
            if(!response.isExists()){
                return null;
            }
            return response.getSourceAsString();
        }finally {
            close();
        }
    }

    /**
     * 删除文档
     * @param indexName 索引名称
     * @param id id
     * @return
     * @throws IOException
     */
    public static String deleteDoc(String indexName, String id) throws IOException {
        try {
            DeleteRequest request = new DeleteRequest();
            request.index(indexName).id(id);
            DeleteResponse response = getClient().delete(request, RequestOptions.DEFAULT);
            return response.getResult().toString();
        }finally {
            close();
        }
    }


    /**
     * 批量添加文档
     * @param esVo 添加的数据
     * @throws IOException
     */
    public static void batchInsert(ESVo esVo) throws Exception {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            ESIterator iterator = esVo.iterator();
            while (iterator.haveNext()){
                ESVo next = iterator.next();
                bulkRequest.add(new IndexRequest()
                        .index(next.getIndex())
                        .id(next.getId()).source(next.getDoc(), XContentType.JSON));
            }
            BulkResponse response = getClient().bulk(bulkRequest, RequestOptions.DEFAULT);
        }finally {
            close();
        }
    }


    /**
     * 批量删除文档
     * @param esVo 添加的数据
     * @throws IOException
     */
    public static void batchDelete(ESVo esVo) throws Exception {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            ESIterator iterator = esVo.iterator();
            while (iterator.haveNext()){
                ESVo next = iterator.next();
                bulkRequest.add(new DeleteRequest()
                        .index(next.getIndex())
                        .id(next.getId()));
            }
            BulkResponse response = getClient().bulk(bulkRequest, RequestOptions.DEFAULT);
        }finally {
            close();
        }
    }


    public static void main(String[] args) throws Exception {


        EsClient.close();
    }
}
